package cn.ncist.health_service_provider.service.impl;

import cn.ncist.constant.RedisConstant;
import cn.ncist.entity.QueryPageBean;
import cn.ncist.health_interface.service.SetMealService;
import cn.ncist.health_service_provider.dao.CheckGroupMapper;
import cn.ncist.health_service_provider.dao.SetMealMapper;
import cn.ncist.health_service_provider.generate.GenerateHtml;
import cn.ncist.health_service_provider.redis.UpdateRedisInfo;
import cn.ncist.pojo.CheckGroup;
import cn.ncist.pojo.CheckItem;
import cn.ncist.pojo.Setmeal;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@Transactional
@DubboService(interfaceClass = SetMealService.class, timeout = 50000)
public class SetMealServiceImpl extends ServiceImpl<SetMealMapper, Setmeal> implements SetMealService {

    @Autowired
    private SetMealMapper setMealMapper;

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    @Autowired
    private GenerateHtml generateHtml;

    @Autowired
    private CheckGroupMapper checkGroupMapper;

    @Autowired
    private UpdateRedisInfo updateRedisInfo;

    private String outPutPath = "E:\\Project\\ncist_health\\health_parent\\health_mobile\\src\\main\\resources\\static";

    public Page<Setmeal> findPage(QueryPageBean queryPageBean) {
        if (queryPageBean.getCurrentPage() == null && queryPageBean.getPageSize() == null) {
            throw new RuntimeException("传参错误");
        }

        Page<Setmeal> pageInfo = new Page<>(queryPageBean.getCurrentPage(), queryPageBean.getPageSize());
        String queryString = queryPageBean.getQueryString();
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(queryString != null && queryString.length() > 0, Setmeal::getName, queryString)
                .or()
                .eq(queryString != null && queryString.length() > 0, Setmeal::getCode, queryString)
                .or()
                .eq(queryString != null && queryString.length() > 0, Setmeal::getHelpCode, queryString);
        this.page(pageInfo,queryWrapper);
        return pageInfo;
    }

    @Override
    public void addSetMeal(Setmeal setmeal, Integer[] checkGroupIds) {
        save(setmeal);
        Integer setmealId = setmeal.getId();
        String imgFileName = setmeal.getImg();
        SetOperations<Object, Object> opsForSet = redisTemplate.opsForSet();
        opsForSet.add(RedisConstant.SETMEAL_PIC_DB_RESOURCES,imgFileName);
        this.setSetMealIdAndCheckGroupId(setmealId,checkGroupIds);

        List<Setmeal> setmealList = (List<Setmeal>) redisTemplate.opsForValue().get("setmealList");
        //判断redis内是否存在缓存
        if(setmealList != null && setmealList.size() > 0){
            setmealList = updateRedisInfo.add(setmealList, setmeal);
            redisTemplate.opsForValue().set("setmealList",setmealList);
        }
        //创建静态页面
//        generateHtml.generateMobileStaticHtml();
    }

    @Override
    public List<Integer> selectCheckGroupIdBySetMealId(Integer setMealId) {
        return setMealMapper.findCheckGroupIdBySetMealId(setMealId);
    }

    @Override
    public void updateBySetMealId(Integer[] checkGroupIds, Setmeal setmeal) {
        this.updateById(setmeal);
        setMealMapper.deleteAssociation(setmeal.getId());
        this.setSetMealIdAndCheckGroupId(setmeal.getId(),checkGroupIds);

        List<Setmeal> setmealList = (List<Setmeal>) redisTemplate.opsForValue().get("setmealList");
        //判断redis内是否存在缓存
        if(setmealList != null && setmealList.size() > 0){
            setmealList = updateRedisInfo.update(setmealList, setmeal);
            redisTemplate.opsForValue().set("setmealList",setmealList);
        }
        //创建静态页面
//        generateHtml.generateMobileStaticHtml();
    }

    @Override
    public void deleteSetMeal(Integer id) {
        this.removeById(id);
        setMealMapper.deleteAssociation(id);

        //删除套餐数据，更新或者添加数据到redis缓存内
        List<Setmeal> setmealList = (List<Setmeal>) redisTemplate.opsForValue().get("setmealList");
        if(setmealList != null && setmealList.size() > 0){
            //redis内存在数据
            //更新数据
            setmealList = updateRedisInfo.delete(setmealList, id);
            redisTemplate.opsForValue().set("setmealList",setmealList);
        }

        //创建静态页面
//        generateHtml.generateMobileStaticHtml();
    }

    @Override
    public List<Setmeal> findAll() {
        //检查redis内是否已经缓存了数据
        if(redisTemplate.opsForValue().get("setmealList") != null){
            List<Setmeal> setmealList = (List<Setmeal>) redisTemplate.opsForValue().get("setmealList");
            return setmealList;
        }
        List<Setmeal> setmealList = this.list();
        for (Setmeal setmeal : setmealList) {
            Integer setmealId = setmeal.getId();
            //根据setmeal的id去查询检查组信息
            List<CheckGroup> checkGroupList = setMealMapper.findCheckGroupsBySetmealId(setmealId);
            for (CheckGroup checkGroup : checkGroupList) {
                //根据checkGroupId查询检查项信息
                Integer checkGroupId = checkGroup.getId();
                List<CheckItem> checkItemList = checkGroupMapper.selectCheckItemFromTableCheckItem(checkGroupId);
                checkGroup.setCheckItems(checkItemList);
            }
            setmeal.setCheckGroups(checkGroupList);
        }
        //将查询到的套餐数据存入redis
        redisTemplate.opsForValue().set("setmealList",setmealList);
        return setmealList;
    }

    @Override
    public Setmeal findById(Integer id) {
        Setmeal setmeal = null;
        //判断redis内是否缓存了套餐数据
        List<Setmeal> setmealList = (List<Setmeal>) redisTemplate.opsForValue().get("setmealList");
        if(setmealList == null || setmealList.size() == 0){
            //redis缓存内不存在数据
            //则查询数据库
            Setmeal DBSetmeal = setMealMapper.findById(id);
            //查询checkGroup数据
            List<CheckGroup> checkGroupList = setMealMapper.findCheckGroupsBySetmealId(id);
            for (CheckGroup checkGroup : checkGroupList) {
                //查询检查项数据
                Integer checkGroupId = checkGroup.getId();
                List<CheckItem> checkItemList = checkGroupMapper.selectCheckItemFromTableCheckItem(checkGroupId);
                checkGroup.setCheckItems(checkItemList);
            }
            DBSetmeal.setCheckGroups(checkGroupList);
            log.info("从数据库中查询到的数据为：{}",DBSetmeal.toString());
            return DBSetmeal;
        }
        //redis缓存内存在数据
        for (Setmeal redisSetmeal : setmealList) {
            if(id.equals(redisSetmeal.getId())){
                setmeal = redisSetmeal;
                break;
            }
        }
        log.info("从redis内查询到的数据为；{}",setmeal.toString());
        return setmeal;
    }

    /**
     * 设置中间表的映射关系
     * @param setMealId
     * @param checkGroupIds
     */
    public void setSetMealIdAndCheckGroupId(Integer setMealId,Integer[] checkGroupIds){
        Map<String, Integer> map = new HashMap<>();
        for (Integer checkGroupId : checkGroupIds) {
            map.put("setmealId",setMealId);
            map.put("checkgroupId",checkGroupId);
            setMealMapper.setSetMealAndCheckGroupId2MiddleTable(map);
        }
    }
}
